package com.hdq.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hdq.constant.JwtClaimsConstant;
import com.hdq.constant.MessageConstant;
import com.hdq.context.BaseContext;
import com.hdq.exception.AccountNotFoundException;
import com.hdq.exception.BannedException;
import com.hdq.exception.DeleteException;
import com.hdq.exception.PasswordErrorException;
import com.hdq.mapper.ManagerMapper;
import com.hdq.mapper.RoleMapper;
import com.hdq.mapper.RoleRuleMapper;
import com.hdq.properties.JwtProperties;
import com.hdq.result.PageResult;
import com.hdq.service.ManagerService;
import com.hdq.utils.JwtUtil;
import dto.ManagerAddDTO;
import dto.ManagerLoginDTO;
import dto.ManagerEditDTO;
import entity.Manager;
import entity.Role;
import entity.Rule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import vo.*;


import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ManagerServiceImpl implements ManagerService {


    @Autowired
    private ManagerMapper managerMapper;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleRuleMapper roleRuleMapper;

    /**
     * 管理员登录
     *
     * @param managerLoginDTO
     */
    @Override
    public String managerLogin(ManagerLoginDTO managerLoginDTO) {
        log.info("管理员登录：{}", managerLoginDTO.getUsername());

        String username = managerLoginDTO.getUsername();
        String password = managerLoginDTO.getPassword();
        Boolean autologin = managerLoginDTO.getAutologin();

//        1、判断数据库是否存在此管理员
        Manager manager = managerMapper.getManagerByUsername(username);
        if (manager == null) {
//            账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
//        2、账号存在，则验证密码
        String encipher_password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!manager.getPassword().equals(encipher_password)) {
//            密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
//        3、验证通过，生成token
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.MANAGER_ID, manager.getId());
//        是否24小时免登录
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                autologin ? 24 * 60 * 60 * 1000 : jwtProperties.getAdminTtl(),
                claims);

        Long managerId= manager.getId();
//        存入redis
        redisTemplate.opsForHash().put(JwtClaimsConstant.TOKEN,managerId,token);

        return token;
    }

    /**
     * 获取管理员信息
     *
     * @return
     */
    @Override
    public ManagerInfoVO getInfo() {
//        获取manager信息
        Long managerId = BaseContext.getCurrentId();
        Manager manager = managerMapper.getManagerById(managerId);
        ManagerInfoVO managerInfoVO = new ManagerInfoVO();
        BeanUtils.copyProperties(manager, managerInfoVO);

//        获取manager的role信息
        Role role = roleMapper.getRoleById(manager.getRoleId());
        RoleInfoVO roleInfoVO = new RoleInfoVO();
        BeanUtils.copyProperties(role, roleInfoVO);

//        获取manager的menus
        Long roleId = role.getId();
//        查询该角色对应的权限
        List<Rule> rules = roleRuleMapper.getRuleInfoByRoleId(roleId,1);
        List<RuleInfoVO> ruleInfoVOs = rulesTransformMenus(rules);

        managerInfoVO.setRole(roleInfoVO);
        managerInfoVO.setMenus(ruleInfoVOs);

        // 查询规则名称的列表
        List<Rule> permission = roleRuleMapper.getRuleInfoByRoleId(roleId,0);
        List<String> ruleNamesList=new ArrayList<>();
        for (Rule r : permission) {
            ruleNamesList.add(r.getCondition()+","+r.getMethod());
        }
        managerInfoVO.setRuleNames(ruleNamesList);

        return managerInfoVO;
    }

    //    获取管理员列表
    @Override
    public PageResult selectByPage(Integer page, Integer pageSize, Manager manager) {
        PageHelper.startPage(page, pageSize);
        Page<ManagerPageVO> list = managerMapper.selectByPage(manager);
        return new PageResult(list.getTotal(), list.getResult());
    }


//    新增管理员


    @Override
    public void insert(ManagerAddDTO managerAddDTO) {
        Manager manager = new Manager();
        BeanUtils.copyProperties(managerAddDTO,manager);
        String password = manager.getPassword();
        manager.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        manager.setIsSuper(0);
        managerMapper.insert(manager);
    }

    @Override
    public void update(Long id, ManagerEditDTO managerEditDTO) {
        Manager manager = new Manager();
        BeanUtils.copyProperties(managerEditDTO,manager);
        String password = manager.getPassword();
        if(password!=null){
            manager.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        }
        System.out.println(manager);
        manager.setId(id);
        managerMapper.update(manager);

    }

    @Override
    @Transactional
    public void delete(List<Long> ids) {
        try{
            managerMapper.delete(ids);
        }catch (Exception e){
            log.error("删除异常：{}",e);
            throw  new DeleteException(MessageConstant.DELETE_FAIL);
        }
    }

    @Override
    @Transactional
    public void banned(List<Long> ids, Integer status) {
        try{
            managerMapper.banned(ids,status);
        }catch (Exception e){
            log.error("封禁异常：{}",e);
            throw  new BannedException(MessageConstant.BANNED_FAIL);
        }
    }

    @Override
    public List<ManagerXiaLalistVO> selectXiaLa() {
        List<ManagerXiaLalistVO> list=managerMapper.selectXiaLa();
        return list;
    }

    private List<RuleInfoVO> rulesTransformMenus(List<Rule> rules) {
//        rule转为ruleVo
        List<RuleInfoVO> ruleInfoVOs = rules.stream().map(this::convertToVO).collect(Collectors.toList());
        Map<Long, RuleInfoVO> ruleMap = ruleInfoVOs.stream().collect(Collectors.toMap(RuleInfoVO::getId, vo -> vo));

        // 创建一个 List 来存储顶级节点
        List<RuleInfoVO> rootNodes = new ArrayList<>();

        for (RuleInfoVO ruleInfoVo : ruleInfoVOs) {
            if (ruleInfoVo.getRuleId() == 0) {
                rootNodes.add(ruleInfoVo);
                continue;
            }
//            寻找父亲节点
            RuleInfoVO parent = ruleMap.get(ruleInfoVo.getRuleId());
//            如果父亲节点不为null
            if (parent != null) {
                if (parent.getChild() == null) {
                    parent.setChild(new ArrayList<>());
                }

                parent.getChild().add(ruleInfoVo);
            }
        }

        return rootNodes;
    }

    private RuleInfoVO convertToVO(Rule rule) {
        RuleInfoVO ruleInfoVO = new RuleInfoVO();
        BeanUtils.copyProperties(rule, ruleInfoVO);
        return ruleInfoVO;
    }

}
